package org.frv.wispr.business;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.transaction.annotation.Transactional;

// TODO inject a method that makes this search not just by name but by name and username
public class AccountServiceImpl implements AccountService {
	private AccountRepository accountRepository;
    private AccountEntryRepository accountEntryRepository;


    // we need to make sure that this
    public Account getAccountById(Long id) {
		// TODO Auto-generated method stub
		return null;
	}


    // this is a key function implenmenting the vast majority of the bussiness logic
    @Transactional
    public void addEntry(Account account, AccountEntry entry, Account reverseAccount, AccountEntry doubleEntry) {
		if (doubleEntry == null) {
            throw new InvalidEntryException("No double entry defined");
        }
        // add lots of checks here! All this code has to implement business rules
        // - credit or debit
        // - valid double entry
        // - calculate correct new value for balance.
        // - etc.
        account.getEntries().add(entry);
        setBalance(account, entry);
        accountRepository.save(account);
        reverseAccount.getEntries().add(doubleEntry);
        setBalance(reverseAccount, doubleEntry);
        accountRepository.save(reverseAccount);

        entry.setDoubleEntry(doubleEntry);
        accountEntryRepository.save(entry);
        doubleEntry.setDoubleEntry(entry);
        accountEntryRepository.save(doubleEntry);
    }

    private void setBalance(Account account, AccountEntry entry) {
            if (account.getAccountType().getCreditIncreasesBalance()) {
                if (entry.getCredit() != null) {
                    account.setBalance(account.getBalance().add(entry.getCredit()));
                } else {
                    account.setBalance((account.getBalance().subtract(entry.getDebit())));
                }
            } else {
                if (entry.getCredit() != null) {
                    account.setBalance(account.getBalance().subtract(entry.getCredit()));
                } else {
                    account.setBalance(account.getBalance().add(entry.getDebit()));
                }
            }
    }

    // make sure this gets done by both name and username
    public Account getAccountByName(String s) {
        return accountRepository.findByName(s);

    }

    public AccountRepository getAccountRepository() {
		return accountRepository;
	}

	@Required
	public void setAccountRepository(AccountRepository accountRepository) {
		this.accountRepository = accountRepository;
	}

    @Required
    public AccountEntryRepository getAccountEntryRepository() {
    return accountEntryRepository;
}

    public void setAccountEntryRepository(AccountEntryRepository accountEntryRepository) {
        this.accountEntryRepository = accountEntryRepository;
    }


}
